package com.imooc.course.server.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.imooc.course.server.dao.SectionDao;
import com.imooc.course.server.dto.SectionDto;
import com.imooc.course.server.dto.SectionPageDto;
import com.imooc.course.server.entity.Section;
import com.imooc.course.server.entity.SectionExample;
import com.imooc.course.server.service.CourseService;
import com.imooc.course.server.service.SectionService;
import com.imooc.course.server.utils.CopyUtil;
import com.imooc.course.server.utils.UuidUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.List;

@Service("sectionService")
public class SectionServiceImpl implements SectionService {

    private static final Logger log = LoggerFactory.getLogger(SectionServiceImpl.class);

    @Resource(name = "sectionDao")
    private SectionDao sectionDao;

    @Resource(name = "courseService")
    private CourseService courseService;
    /**
     * 列表查询
     * @param sectionPageDto
     */
    @Override
    public void getList(SectionPageDto sectionPageDto) {
        PageHelper.startPage(sectionPageDto.getPage(),sectionPageDto.getSize());

        SectionExample sectionExample = new SectionExample();
        SectionExample.Criteria criteria = sectionExample.createCriteria();
        if (!StringUtils.isEmpty(sectionPageDto.getChapterId())) {
            criteria.andChapterIdEqualTo(sectionPageDto.getChapterId());
        }
        if (!StringUtils.isEmpty(sectionPageDto.getCourseId())) {
            criteria.andCourseIdEqualTo(sectionPageDto.getCourseId());
        }
        sectionExample.setOrderByClause("sort asc");
        List<Section> sectionList = sectionDao.selectByExample(sectionExample);

        PageInfo<Section> sectionPageInfo = new PageInfo<>(sectionList);
        sectionPageDto.setTotal(sectionPageInfo.getTotal());

        List<SectionDto> sectionDtoList = CopyUtil.copyList(sectionList, SectionDto.class);

        sectionPageDto.setList(sectionDtoList);
    }

    /**
     * 保存，id有值为更新，id无值为新增
     * @param sectionDto
     */
    /*
    * @Transactional注解默认是RuntimeException才会rollback，
    * 所以如果自定义异常想要被事务rollback，就必须继承RuntimeException。
    * 此外，可以设置rollbackFor属性指定异常回滚。
    * 如：@Transactional(rollbackFor = {Exception.class,RuntimeException.class})
    * 如果在方法中直接处理异常，也要在catch中抛出RuntimeException实现事务回滚。
    * 同一个类内部方法互相调用，A方法调用B方法，B方法的事务不起作用。
    * spring的事务处理是利用aop生成动态代理类，内部方法调用时不经过代理类，所以事务不生效。
    * */
    @Transactional
    @Override
    public void save(SectionDto sectionDto) {
        Section section = CopyUtil.copy(sectionDto, Section.class);
        String id = sectionDto.getId() != null ? sectionDto.getId().trim() : sectionDto.getId();
        if (StringUtils.isEmpty(id)) {
            this.addSection(section);
        }else{
            this.updateSection(section);
        }

    //更新课程时长，course课程时长由section表中所有的time累加得到。
        //逻辑上是可以这么编写的，但不推荐在section表的业务层里面直接调用course表的持久层代码，不利于代码管理。
        //myCourseDao.updateTime(section.getCourseId());
        //应该将更新课程时长的updateTime方法在course的业务层中完成，再在section业务层中调用。
        courseService.updateTime(section.getCourseId());

    }

    private void updateSection(Section copy) {
        sectionDao.updateByPrimaryKeySelective(copy);
    }

    private void addSection(Section copy) {
        copy.setId(UuidUtil.getShortUuid());
        sectionDao.insertSelective(copy);
    }

    /**
     * 删除
     * @param id
     */
    @Override
    public void delete(String id) {
        sectionDao.deleteByPrimaryKey(id);
    }

    @Override
    public List<SectionDto> getListByCourseId(String courseId) {
        SectionExample example = new SectionExample();
        SectionExample.Criteria criteria = example.createCriteria();
        criteria.andCourseIdEqualTo(courseId);
        List<Section> sectionList = sectionDao.selectByExample(example);
        return CopyUtil.copyList(sectionList, SectionDto.class);

    }
}
